import cv2
import numpy as np
import matplotlib.pyplot as plt

# 步骤1：读取图像并预处理
image = cv2.imread('../img/pic2.jpg')  # 替换为你的电镜图路径
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)

# 步骤2：手动输入比例尺信息（避免复杂OCR）
scale_length_pixels = 79  # 用画图工具测量比例尺线段的像素长度
scale_real_length = 10  # 比例尺标注的实际长度（如100nm）
scale_factor = scale_real_length / scale_length_pixels  # 计算单位转换系数

# 步骤3：选择条纹区域（ROI）
# 用OpenCV选择包含条纹的矩形区域
fromCenter = False
r = cv2.selectROI("Select Stripe Area", blur, fromCenter)
cv2.destroyAllWindows()

# 提取ROI区域
roi = blur[int(r[1]):int(r[1] + r[3]), int(r[0]):int(r[0] + r[2])]


# 步骤4：测量条纹间隔（FFT方法）
def measure_stripe_period(roi):
    # 快速傅里叶变换
    fft = np.fft.fft2(roi)
    fft_shift = np.fft.fftshift(fft)
    magnitude = 20 * np.log(np.abs(fft_shift))

    # 找到最大频率点（中心点除外）
    center = np.array(magnitude.shape) // 2
    magnitude[center[0] - 10:center[0] + 11, center[1] - 10:center[1] + 11] = 0  # 屏蔽中心区域
    max_val = np.max(magnitude)
    max_loc = np.where(magnitude == max_val)

    # 计算频率点距离
    distance = np.sqrt((max_loc[0] - center[0]) ** 2 + (max_loc[1] - center[1]) ** 2)[0]

    # 计算条纹周期（像素）
    period_pixels = roi.shape[0] / distance
    return period_pixels


# 步骤5：计算实际物理尺寸
stripe_period_pixels = measure_stripe_period(roi)
stripe_period_real = stripe_period_pixels * scale_factor  # 单位与比例尺一致

print(f"条纹像素间隔: {stripe_period_pixels:.2f} pixels")
print(f"条纹实际间隔: {stripe_period_real:.2f} nm")  # 单位根据比例尺调整